package com.rc.saas.tenant.service.weixin;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.dozermapper.core.Mapper;
import com.rc.saas.tenant.common.component.UidGenerator;
import com.rc.saas.tenant.common.constant.CommonConstant;
import com.rc.saas.tenant.common.utils.StringUtil;
import com.rc.saas.tenant.common.vo.TResponse;
import com.rc.saas.tenant.dto.TransPayWalletInfoDto;
import com.rc.saas.tenant.dto.TransPayWalletResultDto;
import com.rc.saas.tenant.mapper.transfer.MemberRefundApplyMapper;
import com.rc.saas.tenant.model.member.MemberInfo;
import com.rc.saas.tenant.model.tenant.Tenant;
import com.rc.saas.tenant.model.tenant.TenantSetting;
import com.rc.saas.tenant.model.transfer.MemberRefundApply;
import com.rc.saas.tenant.model.transfer.TransferOrder;
import com.rc.saas.tenant.service.tenant.TenantService;
import com.rc.saas.tenant.service.tenant.TenantSettingService;
import com.rc.saas.tenant.service.transfer.TransferOrderService;
import com.rc.saas.tenant.transfers.weixin.WxTransPayWalletVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.weixin4j.pay.WeixinPayException;
import org.weixin4j.pay.http.HttpsClient;
import org.weixin4j.pay.http.Response;
import org.weixin4j.pay.model.paywallet.TransPayWallet;
import org.weixin4j.pay.model.paywallet.TransPayWalletInfo;
import org.weixin4j.pay.model.paywallet.TransPayWalletResult;
import org.weixin4j.pay.util.SignUtil;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 参考PayWalletComponment类
 * Created by Sven on 2021/08/12
 */
@Service
public class WxPayWalletServiceImpl implements WxPayWalletService {
    private static Logger logger = LogManager.getLogger(WxPayWalletServiceImpl.class);

    //企业付款到零钱
    private final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
    //查询企业付款
    private final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";

    //付款失败时，不须使用原商户订单号重试的错误码
    private final String NOT_NEED_RETRY_ERRCODE = "NO_AUTH,AMOUNT_LIMIT,PARAM_ERROR,OPENID_ERROR,XML_ERROR,FATAL_ERROR,RECV_ACCOUNT_NOT_ALLOWED,PAY_CHANNEL_NOT_ALLOWED";//,NAME_MISMATCH

    @Autowired
    private Mapper dozerMapper;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private TenantService tenantService;

    @Autowired
    private TransferOrderService transferOrderService;

    @Autowired
    private MemberRefundApplyMapper memberRefundApplyMapper;

    @Autowired
    private TenantSettingService tenantSettingService;

    /**
     * 微信企业转账接口文档地址： https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
     * @param request
     * @param tenant
     * @param memberInfo
     * @param transPayWalletVo
     * @param tenantSetting
     * @return
     */
    @Override
    public TResponse transPayWallet(HttpServletRequest request, Tenant tenant, MemberInfo memberInfo, WxTransPayWalletVo transPayWalletVo, TenantSetting tenantSetting) {

        //订单总金额，单位为分
        //交易金额默认为人民币交易，接口中参数支付金额单位为【分】，参数值不能带小数。对账单中的交易金额单位为【元】。
        //外币交易的支付金额精确到币种的最小单位，参数值不能带小数点
        BigDecimal targetAmount = transPayWalletVo.getAmount().multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN);
        if (targetAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return TResponse.FAIL("付款金额不合法" + targetAmount);
        }

        //根据不同的运营商简码生成充值订单号
        String outTradeNo = uidGenerator.genWxTransferOutTradeNo(tenant.getTenantPrefix(), memberInfo.getMobile(), CommonConstant.WX_TRANSFER_PREFIX);
        if (outTradeNo == null) {
            return TResponse.FAIL("无法生成付款订单号");
        }

        //生成付款单
        TransferOrder transferOrder = new TransferOrder();
        transferOrder.setTenantCode(tenant.getTenantCode());
        transferOrder.setMemberId(memberInfo.getMemberId());
        transferOrder.setMemberRealName(transPayWalletVo.getRealName());
        transferOrder.setOutTradeNo(outTradeNo);
        transferOrder.setRefundApplyId(transPayWalletVo.getRefundApplyId());//申请单ID
        transferOrder.setAmount(transPayWalletVo.getAmount());//单位（元）

        //充值方式  0后台 1公众号 2 APP  3小程序  默认0
        transferOrder.setTransferType("0");

        //支付方式  0 微信支付  1支付宝 Z0中行微信 Z1中行支付宝 U银联支付
        transferOrder.setPaymentType("0");

        //到帐状态 0未到帐  1已到帐 默认0
        transferOrder.setStatus("0");
        transferOrder.setCreatedTime(new Date());
        transferOrderService.insertSelectiveReturnId(transferOrder);

        //创建企业付款到零钱对象
        TransPayWallet transPayWallet = new TransPayWallet();
        //微信公众号的appid
        transPayWallet.setMch_appid(tenant.getWechatAppid());
        //微信支付商户号
        transPayWallet.setMchid(tenant.getWechatPayMchid());
        //业务流水号（需每次唯一）
        transPayWallet.setPartner_trade_no(outTradeNo);

        //支付给用户openid
        transPayWallet.setOpenid(memberInfo.getWechatOpenid());
        //取消校验用户姓名选项
        //transPayWallet.setCheck_name(true);
        //transPayWallet.setRe_user_name(transPayWalletVo.getRealName());

      //  //TODO 上线前要取消
      //  transPayWallet.setOpenid("o8D5aw5eYZsu-6sr4dqZJbMbu-5w");
      //  transPayWallet.setCheck_name(true);
      //  transPayWallet.setRe_user_name(transPayWalletVo.getRealName());

        //转账金额 1.00元,企业付款金额，最少为100，单位为分
        transPayWallet.setAmount(targetAmount.intValue());

        transPayWallet.setDesc("企业付款");
        transPayWallet.setSpbill_create_ip(request.getRemoteHost());

        logger.info("准备企业付款到零钱:{},:{}", transPayWallet.toString(), tenantSetting.getWxTransferCertPath());

        try {
            //1 转帐
            TransferOrder updateTransferOrder = new TransferOrder();
            TransPayWalletResult transPayWalletResult = transPayWallet(tenant, transPayWallet, tenantSetting.getWxTransferCertPath(), updateTransferOrder);

            //TransPayWalletInfo 转换为 TransPayWalletResultDto
            TransPayWalletResultDto transPayWalletResultDto = dozerMapper.map(transPayWalletResult, TransPayWalletResultDto.class);
            transPayWalletResultDto.setMemberId(memberInfo.getMemberId());
            transPayWalletResultDto.setOpenid(memberInfo.getWechatOpenid());
            transPayWalletResultDto.setPartner_trade_no(transferOrder.getOutTradeNo());

            //根据map中的result_code AND return_code来判断是否成功与失败
            if (!"SUCCESS".equals(transPayWalletResult.getResult_code()) || !"SUCCESS".equals(transPayWalletResult.getReturn_code())) {
                logger.error("result_code/return_code标记不为SUCCESS:{},:{}", transPayWalletResult.getResult_code(), transPayWalletResult.getReturn_code());

                //转账失败,当返回错误码为“SYSTEMERROR”时，请不要更换商户订单号，一定要使用原商户订单号重试，否则可能造成重复支付等资金风险
                doFailTransferOrder(transferOrder.getTransferOrderId(), updateTransferOrder.getRetryTransfersReq(), null, transPayWalletResultDto,transPayWalletVo.getRefundApplyId(),transPayWalletResult.getErr_code_des());

                return TResponse.FAIL("转账失败:" + transPayWalletResult.getErr_code_des());
            }

            //2 查帐
            TransPayWalletInfo transPayWalletInfo = getTransferInfo(tenant, transPayWallet, tenantSetting.getWxTransferCertPath(), updateTransferOrder);

            // 转账状态
            // SUCCESS:转账成功
            // FAILED:转账失败
            // PROCESSING:处理中
            if (transPayWalletInfo == null || transPayWalletInfo.getStatus().equals("FAILED")) {
                //转账失败,当返回错误码为“SYSTEMERROR”时，请不要更换商户订单号，一定要使用原商户订单号重试，否则可能造成重复支付等资金风险
                doFailTransferOrder(transferOrder.getTransferOrderId(), updateTransferOrder.getRetryTransfersReq(), updateTransferOrder.getRetryGettransferinfoReq(), transPayWalletResultDto,transPayWalletVo.getRefundApplyId(),"查账:转账失败");

                return TResponse.FAIL("转账失败");
            }

            //执行成功付款后的业务逻辑
            if (StringUtil.isBlank(transPayWalletResult.getPayment_no()) || StringUtil.isBlank(transPayWalletResult.getPayment_time())) {
                logger.error("payment_no/payment_time为空:{},:{}", transPayWalletResult.getPayment_no(), transPayWalletResult.getPayment_time());

                //转账失败,当返回错误码为“SYSTEMERROR”时，请不要更换商户订单号，一定要使用原商户订单号重试，否则可能造成重复支付等资金风险
                doFailTransferOrder(transferOrder.getTransferOrderId(), updateTransferOrder.getRetryTransfersReq(), updateTransferOrder.getRetryGettransferinfoReq(), transPayWalletResultDto,transPayWalletVo.getRefundApplyId(),transPayWalletResult.getErr_code_des());

                return TResponse.FAIL("转账失败");
            }

            //TransPayWalletInfo 转换为 TransPayWalletInfoDto
            TransPayWalletInfoDto transPayWalletInfoDto = dozerMapper.map(transPayWalletInfo, TransPayWalletInfoDto.class);

            //没有异步通知，只能通过查帐来确认转账成功
            transferOrderService.updateSuccessTransferOrder(transferOrder.getTransferOrderId(), transPayWalletResultDto, transPayWalletInfoDto);

            TResponse tResponse = TResponse.SUCCESS("付款成功");
            tResponse.put(transPayWalletInfo);
            return tResponse;
        } catch (Exception e) {
            logger.error("微信付款异常", e);
            return TResponse.FAIL("转账失败");
        }
    }

    /**
     * 付款
     */
    private TransPayWalletResult transPayWallet(Tenant tenant, TransPayWallet transPayWallet, String certPath, TransferOrder updateTransferOrder)
            throws WeixinPayException {
        //获取微信支付配置
        //WeixinPayConfig weixinPayConfig = weixinPay.getWeixinPayConfig();
        //创建RSA公钥请求对象
        String mchId = transPayWallet.getMchid();
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");

        //数据签名
        Map<String, String> map = new HashMap<String, String>();
        map.put("mch_appid", transPayWallet.getMch_appid());
        map.put("mchid", mchId);
        map.put("nonce_str", nonceStr);
        map.put("partner_trade_no", transPayWallet.getPartner_trade_no());
        map.put("openid", transPayWallet.getOpenid());
        if (transPayWallet.getCheck_name()) {
            //强校验真实姓名
            map.put("check_name", "FORCE_CHECK");
            if (StringUtils.isBlank(transPayWallet.getRe_user_name())) {
                return null;
            }
            map.put("re_user_name", transPayWallet.getRe_user_name());
        } else {
            //不校验真实姓名
            map.put("check_name", "NO_CHECK");
        }
        map.put("amount", transPayWallet.getAmount() + "");
        map.put("desc", transPayWallet.getDesc());
        map.put("spbill_create_ip", transPayWallet.getSpbill_create_ip());

        //数据签名(微信支付_商户密钥(32位))
        String sign = SignUtil.getSign(map, tenant.getWechatPaySecret());

        //封装提交数据
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        sb.append("<mch_appid>").append(transPayWallet.getMch_appid()).append("</mch_appid>");
        sb.append("<mchid>").append(mchId).append("</mchid>");
        sb.append("<nonce_str>").append(nonceStr).append("</nonce_str>");
        sb.append("<partner_trade_no>").append(transPayWallet.getPartner_trade_no()).append("</partner_trade_no>");
        sb.append("<openid>").append(transPayWallet.getOpenid()).append("</openid>");
        if (transPayWallet.getCheck_name()) {
            sb.append("<check_name>FORCE_CHECK</check_name>");
            sb.append("<re_user_name>").append(transPayWallet.getRe_user_name()).append("</re_user_name>");
        } else {
            sb.append("<check_name>NO_CHECK</check_name>");
        }
        sb.append("<amount>").append(transPayWallet.getAmount()).append("</amount>");
        sb.append("<desc>").append(transPayWallet.getDesc()).append("</desc>");
        sb.append("<spbill_create_ip>").append(transPayWallet.getSpbill_create_ip()).append("</spbill_create_ip>");
        sb.append("<sign>").append(sign).append("</sign>");
        sb.append("</xml>");
        String xml = sb.toString();

        //<xml>
        //<mch_appid>wx4a07aac285316f94</mch_appid>
        //<mchid>1413266002</mchid>
        //<nonce_str>b9ea51fa2ea44972a25dcae259055c20</nonce_str>
        //<partner_trade_no>JWX202004271953001</partner_trade_no>
        //<openid>o8D5aw-4D-duzJ2ubj636m8LqJK8</openid>
        //<check_name>FORCE_CHECK</check_name>
        //<re_user_name>吴思源</re_user_name>
        //<amount>100</amount>
        //<desc>退款</desc>
        //<spbill_create_ip>192.168.0.1</spbill_create_ip>
        //<sign>17FAC5513A111581260B359E62C21772</sign>
        //</xml>

        //保存XML报文
        updateTransferOrder.setRetryTransfersReq(xml);

        //if (Configuration.isDebug()) {
        logger.info("调试模式_企业付款到零钱接口 提交XML数据：" + xml);
        //}

        HttpsClient httpsClient = new HttpsClient();
        //发起请求，企业付款到零钱API,，证书密钥(默认与商户号一致)
        Response response = httpsClient.postXmlWithCert(TRANSFERS_URL, xml, mchId, certPath, tenant.getWechatPayMchid());

        //获取返回内容
        String xmlResult = response.asString();
        //if (Configuration.isDebug()) {
        logger.info("调试模式_企业付款到零钱接口 返回XML数据：" + xmlResult);
        //}
        try {
            //创建XML解析对象
            JAXBContext context = JAXBContext.newInstance(TransPayWalletResult.class);
            XMLInputFactory xif = XMLInputFactory.newFactory();
            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
            xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
            //防XXE攻击
            XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xmlResult));
            Unmarshaller unmarshaller = context.createUnmarshaller();
            //解析XML对象
            TransPayWalletResult transPayWalletResult = (TransPayWalletResult) unmarshaller.unmarshal(xsr);
            if (!"SUCCESS".equals(transPayWalletResult.getReturn_code())) {
                throw new WeixinPayException(transPayWalletResult.getReturn_msg());
            }
            return transPayWalletResult;
        } catch (JAXBException | XMLStreamException ex) {
            return null;
        }
    }

    @Override
    public TransPayWalletInfo getTransferInfo(Tenant tenant, TransPayWallet transPayWallet, String certPath, TransferOrder updateTransferOrder) {
        //获取微信支付配置
        //WeixinPayConfig weixinPayConfig = weixinPay.getWeixinPayConfig();
        String mchId = transPayWallet.getMchid();
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");

        //数据签名
        Map<String, String> map = new HashMap<String, String>();
        map.put("mch_id", mchId);
        map.put("nonce_str", nonceStr);
        map.put("partner_trade_no", transPayWallet.getPartner_trade_no());
        map.put("appid", transPayWallet.getMch_appid());

        //数据签名
        String sign = SignUtil.getSign(map, tenant.getWechatPaySecret());
        //封装提交数据
        String xml = "<xml>"
                + "<mch_id>" + mchId + "</mch_id>"
                + "<nonce_str>" + nonceStr + "</nonce_str>"
                + "<partner_trade_no>" + transPayWallet.getPartner_trade_no() + "</partner_trade_no>"
                + "<appid>" + transPayWallet.getMch_appid() + "</appid>"
                + "<sign>" + sign + "</sign>"
                + "</xml>";

        //发起请求，查询企业付款到零钱结果
        HttpsClient httpsClient = new HttpsClient();
        //if (Configuration.isDebug()) {
        logger.info("查询企业付款到零钱接口 提交XML数据：" + xml);
        //}

        try {
            //发起请求，查询企业付款到零钱API，证书密钥(默认与商户号一致)
            Response response = httpsClient.postXmlWithCert(GETTRANSFERINFO_URL, xml, mchId, certPath, tenant.getWechatPayMchid());

            //获取返回内容
            String xmlResult = response.asString();

            //保存XML报文
            updateTransferOrder.setRetryGettransferinfoReq(xml);

            //if (Configuration.isDebug()) {
            logger.info("查询企业付款到零钱接口 返回XML数据：" + xmlResult);
            //}

            //创建XML解析对象
            JAXBContext context = JAXBContext.newInstance(TransPayWalletInfo.class);
            XMLInputFactory xif = XMLInputFactory.newFactory();
            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
            xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);

            //防XXE攻击
            XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xmlResult));
            Unmarshaller unmarshaller = context.createUnmarshaller();
            //解析XML对象
            TransPayWalletInfo transPayWalletInfo = (TransPayWalletInfo) unmarshaller.unmarshal(xsr);

            if (!"SUCCESS".equals(transPayWalletInfo.getResult_code()) && !"SUCCESS".equals(transPayWalletInfo.getReturn_code())) {
                logger.error("result_code/return_code标记不为SUCCESS:{},:{}", transPayWalletInfo.getResult_code(), transPayWalletInfo.getReturn_code());
                return null;
            }

            return transPayWalletInfo;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 转账失败处理
     */
    private void doFailTransferOrder(Long transferOrderId, String retryTransfersReq, String retryGettransferinfoReq, TransPayWalletResultDto transPayWalletResultDto
            , Long refundApplyId,String errCodeDes)
            throws JsonProcessingException {
        //转账失败,当返回错误码为“SYSTEMERROR”时，请不要更换商户订单号，一定要使用原商户订单号重试，否则可能造成重复支付等资金风险
        transferOrderService.updateFailTransferOrder(transferOrderId, retryTransfersReq, retryGettransferinfoReq, transPayWalletResultDto);

        MemberRefundApply memberRefundApply = memberRefundApplyMapper.selectByPrimaryKey(refundApplyId);

        memberRefundApply.setStatus("5");
        memberRefundApply.setRemark(errCodeDes);

     //   //发送消息重试
     //   if (NOT_NEED_RETRY_ERRCODE.indexOf(transPayWalletResultDto.getErr_code()) < 0) {
//
     //       memberRefundApply.setStatus("3");
//
     //       logger.info("发送消息重试企业付款到零钱:{}", transPayWalletResultDto.toString());
//
     //       ObjectMapper objectMapper = new ObjectMapper();
     //       String msg = objectMapper.writeValueAsString(transPayWalletResultDto);
     //       mqProducer.send(MqConfig.TRANSFER_ORDER_FAIL, msg,5);
     //   }else {
     //       memberRefundApply.setStatus("5");
     //       memberRefundApply.setRemark(errCodeDes);
     //   }

        memberRefundApplyMapper.updateByPrimaryKeySelective(memberRefundApply);
    }

    @Override
    public TransPayWalletInfo getTransferInfo(TransPayWalletResultDto transPayWalletResultDto) {
        TenantSetting tenantSetting = tenantSettingService.selectByPrimaryKey(transPayWalletResultDto.getTenantCode());
        if (tenantSetting == null || StringUtils.isBlank(tenantSetting.getWxTransferCertPath())) {
            logger.error("找不到商户证书文件");
            return null;
        }

        Tenant tenant = tenantService.selectByPrimaryKey(transPayWalletResultDto.getTenantCode());

        TransferOrder transferOrder = transferOrderService.selectTransferOrderByOutTradeNo(transPayWalletResultDto.getTenantCode(), transPayWalletResultDto.getPartner_trade_no());
        if (transferOrder == null) {
            logger.error("付款单不存在:{}", transPayWalletResultDto.getPartner_trade_no());
            return null;
        }

        String mchId = tenant.getWechatPayMchid();

        //封装提交数据
        String xml = transferOrder.getRetryGettransferinfoReq();

        //发起请求，查询企业付款到零钱结果
        HttpsClient httpsClient = new HttpsClient();
        //if (Configuration.isDebug()) {
        logger.info("查询企业付款到零钱接口 提交XML数据：" + xml);
        //}

        try {
            //发起请求，查询企业付款到零钱API
            Response response = httpsClient.postXmlWithCert(GETTRANSFERINFO_URL, xml, mchId, tenantSetting.getWxTransferCertPath(), tenant.getWechatPayMchid());

            //获取返回内容
            String xmlResult = response.asString();

            //if (Configuration.isDebug()) {
            logger.info("查询企业付款到零钱接口 返回XML数据：" + xmlResult);
            //}

            //创建XML解析对象
            JAXBContext context = JAXBContext.newInstance(TransPayWalletInfo.class);
            XMLInputFactory xif = XMLInputFactory.newFactory();
            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
            xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);

            //防XXE攻击
            XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xmlResult));
            Unmarshaller unmarshaller = context.createUnmarshaller();
            //解析XML对象
            TransPayWalletInfo transPayWalletInfo = (TransPayWalletInfo) unmarshaller.unmarshal(xsr);

            if (!"SUCCESS".equals(transPayWalletInfo.getResult_code()) && !"SUCCESS".equals(transPayWalletInfo.getReturn_code())) {
                logger.error("result_code/return_code标记不为SUCCESS:{},:{}", transPayWalletInfo.getResult_code(), transPayWalletInfo.getReturn_code());
                return null;
            }

            return transPayWalletInfo;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 付款
     */
    @Override
    public TransPayWalletResult transPayWallet(TransPayWalletResultDto transPayWalletResultDto) {
        TenantSetting tenantSetting = tenantSettingService.selectByPrimaryKey(transPayWalletResultDto.getTenantCode());
        if (tenantSetting == null || StringUtils.isBlank(tenantSetting.getWxTransferCertPath())) {
            logger.error("找不到商户证书文件");
            return null;
        }

        Tenant tenant = tenantService.selectByPrimaryKey(transPayWalletResultDto.getTenantCode());

        TransferOrder transferOrder = transferOrderService.selectTransferOrderByOutTradeNo(transPayWalletResultDto.getTenantCode(), transPayWalletResultDto.getPartner_trade_no());
        if (transferOrder == null) {
            logger.error("付款单不存在:{}", transPayWalletResultDto.getPartner_trade_no());
            return null;
        }

        String mchId = tenant.getWechatPayMchid();

        //封装提交数据
        String xml = transferOrder.getRetryTransfersReq();

        HttpsClient httpsClient = new HttpsClient();

        try {
            logger.info("调试模式_企业付款到零钱接口 提交XML数据：" + xml);

            //发起请求，企业付款到零钱API
            Response response = httpsClient.postXmlWithCert(TRANSFERS_URL, xml, mchId, tenantSetting.getWxTransferCertPath(), tenant.getWechatPayMchid());

            //获取返回内容
            String xmlResult = response.asString();

            //if (Configuration.isDebug()) {
            logger.info("调试模式_企业付款到零钱接口 返回XML数据：" + xmlResult);
            //}

            //创建XML解析对象
            JAXBContext context = JAXBContext.newInstance(TransPayWalletResult.class);
            XMLInputFactory xif = XMLInputFactory.newFactory();
            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
            xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
            //防XXE攻击
            XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xmlResult));
            Unmarshaller unmarshaller = context.createUnmarshaller();
            //解析XML对象
            TransPayWalletResult transPayWalletResult = (TransPayWalletResult) unmarshaller.unmarshal(xsr);
            if (!"SUCCESS".equals(transPayWalletResult.getReturn_code())) {
                throw new WeixinPayException(transPayWalletResult.getReturn_msg());
            }
            return transPayWalletResult;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public TransPayWalletInfo retryTransPayWallet(TransPayWalletResultDto transPayWalletResultDto) {
        //1 先查询是否已支付成功,查询企业付款API只支持查询30天内的订单，30天之前的订单请登录商户平台查询
        // 转账状态
        // SUCCESS:转账成功
        // FAILED:转账失败
        // PROCESSING:处理中
        TransPayWalletInfo transPayWalletInfo = getTransferInfo(transPayWalletResultDto);
        if (transPayWalletInfo != null || !transPayWalletInfo.getStatus().equals("FAILED")) {
            logger.info("重试付款,转帐已成功或在处理中:{}", transPayWalletResultDto.toString());
            return transPayWalletInfo;
        }

        //2 FAILED:转账失败,重试付款
        TransPayWalletResult transPayWalletResult = transPayWallet(transPayWalletResultDto);
        //根据map中的result_code AND return_code来判断是否成功与失败
        if (!"SUCCESS".equals(transPayWalletResult.getResult_code()) && !"SUCCESS".equals(transPayWalletResult.getReturn_code())) {
            logger.error("重试付款,result_code/return_code标记不为SUCCESS:{},:{}", transPayWalletResult.getResult_code(), transPayWalletResult.getReturn_code());
            return null;
        }

        //3 先查询是否已支付成功,查询企业付款API只支持查询30天内的订单，30天之前的订单请登录商户平台查询
        // 转账状态
        // SUCCESS:转账成功
        // FAILED:转账失败
        // PROCESSING:处理中
        TransPayWalletInfo transPayWalletInfo2 = getTransferInfo(transPayWalletResultDto);
        if (transPayWalletInfo2 != null || !transPayWalletInfo2.getStatus().equals("FAILED")) {
            logger.info("重试付款,转帐已成功或在处理中:{}", transPayWalletResultDto.toString());
            return transPayWalletInfo;
        }

        //执行成功付款后的业务逻辑
        if (StringUtil.isBlank(transPayWalletResult.getPayment_no()) || StringUtil.isBlank(transPayWalletResult.getPayment_time())) {
            logger.error("重试付款,payment_no/payment_time为空:{},:{}", transPayWalletResult.getPayment_no(), transPayWalletResult.getPayment_time());
            return null;
        }

        //TransPayWalletInfo 转换为 TransPayWalletInfoDto
        TransPayWalletInfoDto transPayWalletInfoDto = dozerMapper.map(transPayWalletInfo, TransPayWalletInfoDto.class);

        //转账成功
        TransferOrder transferOrder = transferOrderService.selectTransferOrderByOutTradeNo(transPayWalletResultDto.getTenantCode(), transPayWalletResultDto.getPartner_trade_no());
        if (transferOrder == null) {
            logger.error("付款单不存在:{}", transPayWalletResultDto.getPartner_trade_no());
            return null;
        }

        //转帐成功后更新订单信息
        transferOrderService.updateSuccessTransferOrder(transferOrder.getTransferOrderId(), transPayWalletResultDto, transPayWalletInfoDto);

        return transPayWalletInfo2;
    }
}
